from functools import wraps
from time import time
from typing import Callable, Sequence, Any, Mapping

from .log import logger
from .utils import get_h_m_s, x2path


def timestamp(func: Callable) -> Callable:
    @wraps(func)
    def decorator(*args, **kwargs) -> Any:
        _start = time()
        res = func(*args, **kwargs)
        _end = time()
        _hour, _minute, _second = get_h_m_s(_end - _start)
        logger.info(
            f"{func.__name__}"
            f"，执行时间："
            f"{_hour} 小时，"
            f"{_minute} 分钟，"
            f"{round(_second, 3)} 秒"
        )
        return res

    return decorator


def param2path(mapping: Mapping, mk: Sequence = (),
               d: int = -1) -> Callable:
    """
    装饰器 指定参数字符串转 Path 类型
    Args:
        mapping: {命名参数的键: 位置参数的下标}
        mk: 要创建文件夹的参数名称
        d: 验证数据有效性，当数据有效时才创建文件夹

    Returns:

    """

    def wrapper(func: Callable) -> Callable:
        @wraps(func)
        def decorator(*args, **kwargs) -> Any:
            args = list(args)
            if d < 0:
                _valid = True
            else:
                _valid = len(args[d]) > 0
            for k, i in mapping.items():
                _is_mk = _valid and k in mk  # 是否创建路径文件夹
                if abs(i) < len(args):
                    args[i] = x2path(args[i], _is_mk)
                if k in kwargs:
                    kwargs[k] = x2path(kwargs[k], _is_mk)
            return func(*args, **kwargs)

        return decorator

    return wrapper
